#include "mce.h"
-int mce_disabled = 0;
+int mce_disabled;
invbool_param("mce", mce_disabled);
-int is_mc_panic = 0;
+int is_mc_panic;
unsigned int nr_mce_banks;
static uint64_t g_mcg_cap;
cpu_banks_t mca_allbanks;
+int mce_verbosity;
+static void __init mce_set_verbosity(char *str)
+{
+ if (strcmp("verbose", str) == 0)
+ mce_verbosity = MCE_VERBOSE;
+ else
+ printk(KERN_DEBUG "Machine Check verbosity level %s not recognised"
+ "use mce_verbosity=verbose", str);
+}
+custom_param("mce_verbosity", mce_set_verbosity);
+
/* Handle unconfigured int18 (should never happen) */
static void unexpected_machine_check(struct cpu_user_regs *regs, long error_code)
{
case MSR_IA32_MCG_STATUS:
*val = d->arch.vmca_msrs.mcg_status;
if (*val)
- gdprintk(XENLOG_DEBUG,
+ mce_printk(MCE_VERBOSE,
"MCE: rdmsr MCG_STATUS 0x%"PRIx64"\n", *val);
break;
case MSR_IA32_MCG_CAP:
*val = d->arch.vmca_msrs.mcg_cap;
- gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCG_CAP 0x%"PRIx64"\n",
+ mce_printk(MCE_VERBOSE, "MCE: rdmsr MCG_CAP 0x%"PRIx64"\n",
*val);
break;
case MSR_IA32_MCG_CTL:
*val = d->arch.vmca_msrs.mcg_ctl;
- gdprintk(XENLOG_DEBUG, "MCE: rdmsr MCG_CTL 0x%"PRIx64"\n",
+ mce_printk(MCE_VERBOSE, "MCE: rdmsr MCG_CTL 0x%"PRIx64"\n",
*val);
break;
case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * MAX_NR_BANKS - 1:
bank = (msr - MSR_IA32_MC0_CTL) / 4;
if ( bank >= (d->arch.vmca_msrs.mcg_cap & MCG_CAP_COUNT) )
{
- gdprintk(XENLOG_WARNING, "MCE: bank %u does not exist\n", bank);
+ mce_printk(MCE_QUIET, "MCE: bank %u does not exist\n", bank);
ret = -1;
break;
}
{
case MSR_IA32_MC0_CTL:
*val = d->arch.vmca_msrs.mci_ctl[bank];
- gdprintk(XENLOG_DEBUG, "MCE: rdmsr MC%u_CTL 0x%"PRIx64"\n",
+ mce_printk(MCE_VERBOSE, "MCE: rdmsr MC%u_CTL 0x%"PRIx64"\n",
bank, *val);
break;
case MSR_IA32_MC0_STATUS:
struct bank_entry, list);
if (entry->bank == bank) {
*val = entry->mci_status;
- gdprintk(XENLOG_DEBUG,
+ mce_printk(MCE_VERBOSE,
"MCE: rd MC%u_STATUS in vMCE# context "
"value 0x%"PRIx64"\n", bank, *val);
}
if ( entry->bank == bank )
{
*val = entry->mci_addr;
- gdprintk(XENLOG_DEBUG,
+ mce_printk(MCE_VERBOSE,
"MCE: rdmsr MC%u_ADDR in vMCE# context "
"0x%"PRIx64"\n", bank, *val);
}
if ( entry->bank == bank )
{
*val = entry->mci_misc;
- gdprintk(XENLOG_DEBUG,
+ mce_printk(MCE_VERBOSE,
"MCE: rd MC%u_MISC in vMCE# context "
"0x%"PRIx64"\n", bank, *val);
}
case MSR_IA32_MCG_CTL:
if ( val && (val + 1) )
{
- gdprintk(XENLOG_WARNING, "MCE: val \"%"PRIx64"\" written "
+ mce_printk(MCE_QUIET, "MCE: val \"%"PRIx64"\" written "
"to MCG_CTL should be all 0s or 1s\n", val);
ret = -1;
break;
break;
case MSR_IA32_MCG_STATUS:
d->arch.vmca_msrs.mcg_status = val;
- gdprintk(XENLOG_DEBUG, "MCE: wrmsr MCG_STATUS %"PRIx64"\n", val);
+ mce_printk(MCE_VERBOSE, "MCE: wrmsr MCG_STATUS %"PRIx64"\n", val);
/* For HVM guest, this is the point for deleting vMCE injection node */
if ( d->is_hvm && (d->arch.vmca_msrs.nr_injection > 0) )
{
entry = list_entry(d->arch.vmca_msrs.impact_header.next,
struct bank_entry, list);
if ( entry->mci_status & MCi_STATUS_VAL )
- gdprintk(XENLOG_ERR, "MCE: MCi_STATUS MSR should have "
+ mce_printk(MCE_QUIET, "MCE: MCi_STATUS MSR should have "
"been cleared before write MCG_STATUS MSR\n");
- gdprintk(XENLOG_DEBUG, "MCE: Delete HVM last injection "
+ mce_printk(MCE_QUIET, "MCE: Delete HVM last injection "
"Node, nr_injection %u\n",
d->arch.vmca_msrs.nr_injection);
list_del(&entry->list);
xfree(entry);
}
else
- gdprintk(XENLOG_WARNING, "MCE: Not found HVM guest"
+ mce_printk(MCE_QUIET, "MCE: Not found HVM guest"
" last injection Node, something Wrong!\n");
}
break;
case MSR_IA32_MCG_CAP:
- gdprintk(XENLOG_WARNING, "MCE: MCG_CAP is read-only\n");
+ mce_printk(MCE_QUIET, "MCE: MCG_CAP is read-only\n");
ret = -1;
break;
case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * MAX_NR_BANKS - 1:
bank = (msr - MSR_IA32_MC0_CTL) / 4;
if ( bank >= (d->arch.vmca_msrs.mcg_cap & MCG_CAP_COUNT) )
{
- gdprintk(XENLOG_WARNING, "MCE: bank %u does not exist\n", bank);
+ mce_printk(MCE_QUIET, "MCE: bank %u does not exist\n", bank);
ret = -1;
break;
}
case MSR_IA32_MC0_CTL:
if ( val && (val + 1) )
{
- gdprintk(XENLOG_WARNING, "MCE: val written to MC%u_CTL "
+ mce_printk(MCE_QUIET, "MCE: val written to MC%u_CTL "
"should be all 0s or 1s (is %"PRIx64")\n",
bank, val);
ret = -1;
struct bank_entry, list);
if ( entry->bank == bank )
entry->mci_status = val;
- gdprintk(XENLOG_DEBUG,
+ mce_printk(MCE_VERBOSE,
"MCE: wr MC%u_STATUS %"PRIx64" in vMCE#\n",
bank, val);
}
else
- gdprintk(XENLOG_DEBUG,
+ mce_printk(MCE_VERBOSE,
"MCE: wr MC%u_STATUS %"PRIx64"\n", bank, val);
break;
case MSR_IA32_MC0_ADDR:
- gdprintk(XENLOG_WARNING, "MCE: MC%u_ADDR is read-only\n", bank);
+ mce_printk(MCE_QUIET, "MCE: MC%u_ADDR is read-only\n", bank);
ret = -1;
break;
case MSR_IA32_MC0_MISC:
- gdprintk(XENLOG_WARNING, "MCE: MC%u_MISC is read-only\n", bank);
+ mce_printk(MCE_QUIET, "MCE: MC%u_MISC is read-only\n", bank);
ret = -1;
break;
}
/* Not impact a valid domain, skip this error of the bank */
if (!d) {
- printk(KERN_DEBUG "MCE: Not found valid impacted DOM\n");
+ mce_printk(MCE_QUIET, "MCE: Not found valid impacted DOM\n");
return 0;
}
*/
if ( (d->is_hvm) && (d->arch.vmca_msrs.nr_injection > 0) )
{
- printk(KERN_DEBUG "MCE: HVM guest has not handled previous"
+ mce_printk(MCE_QUIET, "MCE: HVM guest has not handled previous"
" vMCE yet!\n");
return -1;
}
d->arch.vmca_msrs.nr_injection++;
spin_unlock(&d->arch.vmca_msrs.lock);
- printk(KERN_DEBUG "MCE: Found error @[BANK%d "
+ mce_printk(MCE_VERBOSE,"MCE: Found error @[BANK%d "
"status %"PRIx64" addr %"PRIx64" domid %d]\n ",
mc_bank->mc_bank, mc_bank->mc_status, mc_bank->mc_addr,
mc_bank->mc_domid);
{
if (d->is_hvm)
{
- printk(KERN_DEBUG "MCE: inject vMCE to HVM DOM %d\n",
+ mce_printk(MCE_VERBOSE, "MCE: inject vMCE to HVM DOM %d\n",
d->domain_id);
vcpu_kick(d->vcpu[0]);
}
/* PV guest including DOM0 */
else
{
- printk(KERN_DEBUG "MCE: inject vMCE to PV DOM%d\n",
+ mce_printk(MCE_VERBOSE, "MCE: inject vMCE to PV DOM%d\n",
d->domain_id);
if (guest_has_trap_callback
(d, 0, TRAP_machine_check))
d->vcpu[0]->cpu_affinity;
cpus_clear(affinity);
cpu_set(cpu, affinity);
- printk(KERN_DEBUG "MCE: CPU%d set affinity, old %d\n", cpu,
+ mce_printk(MCE_VERBOSE, "MCE: CPU%d set affinity, old %d\n", cpu,
d->vcpu[0]->processor);
vcpu_set_affinity(d->vcpu[0], &affinity);
vcpu_kick(d->vcpu[0]);
}
else
{
- printk(KERN_DEBUG "MCE: Kill PV guest with No MCE handler\n");
+ mce_printk(MCE_VERBOSE, "MCE: Kill PV guest with No MCE handler\n");
domain_crash(d);
}
}
* in this case, inject fail. [We can't lose this vMCE for
* the mce node's consistency].
*/
- printk(KERN_DEBUG "There's a pending vMCE waiting to be injected "
+ mce_printk(MCE_QUIET, "There's a pending vMCE waiting to be injected "
" to this DOM%d!\n", d->domain_id);
return -1;
}
unsigned long mfn, gfn;
uint32_t status;
- printk(KERN_DEBUG "MCE: Enter UCR recovery action\n");
+ mce_printk(MCE_VERBOSE, "MCE: Enter UCR recovery action\n");
result->result = MCA_NEED_RESET;
if (bank->mc_addr != 0) {
mfn = bank->mc_addr >> PAGE_SHIFT;
if (status & PG_OFFLINE_OWNED) {
result->result |= MCA_OWNER;
result->owner = status >> PG_OFFLINE_OWNER_SHIFT;
- printk(KERN_DEBUG "MCE: This error page is ownded"
+ mce_printk(MCE_QUIET, "MCE: This error page is ownded"
" by DOM %d\n", result->owner);
/* Fill vMCE# injection and vMCE# MSR virtualization "
* "related data */
gfn << PAGE_SHIFT | (bank->mc_addr & PAGE_MASK);
if (fill_vmsr_data(bank, global->mc_gstatus) == -1)
{
- printk(KERN_DEBUG "Fill vMCE# data for DOM%d "
+ mce_printk(MCE_QUIET, "Fill vMCE# data for DOM%d "
"failed\n", result->owner);
domain_crash(d);
return;
/* We will inject vMCE to DOMU*/
if ( inject_mce(d) < 0 )
{
- printk(KERN_DEBUG "inject vMCE to DOM%d"
+ mce_printk(MCE_QUIET, "inject vMCE to DOM%d"
" failed\n", d->domain_id);
domain_crash(d);
return;
mc_panic("MCE: Software recovery failed for the UCR "
"error\n");
else if (mca_res.result == MCA_RECOVERED)
- printk(KERN_DEBUG "MCE: The UCR error is succesfully "
- "recovered by software!\n");
+ mce_printk(MCE_VERBOSE, "MCE: The UCR error is"
+ "successfully recovered by software!\n");
else if (mca_res.result == MCA_NO_ACTION)
- printk(KERN_DEBUG "MCE: Overwrite SRAO error can't execute "
- "recover action, RIPV=1, let it be.\n");
+ mce_printk(MCE_VERBOSE, "MCE: Overwrite SRAO error can't"
+ "do recover action, RIPV=1, let it be.\n");
break;
}
}
* in MCA Handler
*/
if ( i >= INTEL_MAX_RECOVERY )
- printk(KERN_DEBUG "MCE: No software recovery action found for "
- "this SRAO error\n");
+ mce_printk(MCE_VERBOSE, "MCE: No software recovery action"
+ " found for this SRAO error\n");
}
return 1;
int cpu = smp_processor_id();
unsigned int workcpu;
- printk(KERN_DEBUG "CPU%d enter softirq\n", cpu);
+ mce_printk(MCE_VERBOSE, "CPU%d enter softirq\n", cpu);
mce_barrier_enter(&mce_inside_bar);
/* We choose severity_cpu for further processing */
if (atomic_read(&severity_cpu) == cpu) {
- printk(KERN_DEBUG "CPU%d handling errors\n", cpu);
+ mce_printk(MCE_VERBOSE, "CPU%d handling errors\n", cpu);
/* Step1: Fill DOM0 LOG buffer, vMCE injection buffer and
* vMCE MSRs virtualization buffer
/* Step2: Send Log to DOM0 through vIRQ */
if (dom0 && guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
- printk(KERN_DEBUG "MCE: send MCE# to DOM0 through virq\n");
+ mce_printk(MCE_VERBOSE, "MCE: send MCE# to DOM0 through virq\n");
send_guest_global_virq(dom0, VIRQ_MCA);
}
}
}
atomic_set(&found_error, 1);
- printk(KERN_DEBUG "MCE: clear_bank map %lx on CPU%d\n",
+ mce_printk(MCE_VERBOSE, "MCE: clear_bank map %lx on CPU%d\n",
*((unsigned long*)clear_bank), smp_processor_id());
mcheck_mca_clearbanks(clear_bank);
/* Print MCE error */
/* Clear error finding flags after all cpus finishes above judgement */
mce_barrier_enter(&mce_trap_bar);
if (atomic_read(&found_error)) {
- printk(KERN_DEBUG "MCE: Choose one CPU "
+ mce_printk(MCE_VERBOSE, "MCE: Choose one CPU "
"to clear error finding flag\n ");
atomic_set(&found_error, 0);
}
mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus);
if ((gstatus & MCG_STATUS_MCIP) != 0) {
- printk(KERN_DEBUG "MCE: Clear MCIP@ last step");
+ mce_printk(MCE_VERBOSE, "MCE: Clear MCIP@ last step");
mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP);
}
mce_barrier_exit(&mce_trap_bar);
else if ( ser_support && !(status & MCi_STATUS_OVER)
&& !(status & MCi_STATUS_PCC) && (status & MCi_STATUS_S)
&& (status & MCi_STATUS_AR) ) {
- printk(KERN_DEBUG "MCE: No SRAR error defined currently.\n");
+ mce_printk(MCE_VERBOSE, "MCE: No SRAR error defined currently.\n");
return 0;
}
/* SRAO error */
mctelem_cookie_t mctc;
struct mca_summary bs;
- printk(KERN_DEBUG "CMCI: find owner on CPU%d\n", smp_processor_id());
+ mce_printk(MCE_VERBOSE, "CMCI: find owner on CPU%d\n", smp_processor_id());
spin_lock_irqsave(&cmci_discover_lock, flags);
} else if (mctc != NULL)
mctelem_dismiss(mctc);
- printk(KERN_DEBUG "CMCI: CPU%d owner_map[%lx], no_cmci_map[%lx]\n",
- smp_processor_id(),
- *((unsigned long *)__get_cpu_var(mce_banks_owned)),
+ mce_printk(MCE_VERBOSE, "CMCI: CPU%d owner_map[%lx], no_cmci_map[%lx]\n",
+ smp_processor_id(),
+ *((unsigned long *)__get_cpu_var(mce_banks_owned)),
*((unsigned long *)__get_cpu_var(no_cmci_banks)));
}
if (!cmci_support || mce_disabled == 1)
return;
- printk(KERN_DEBUG "CMCI: clear_cmci support on CPU%d\n",
+ mce_printk(MCE_VERBOSE, "CMCI: clear_cmci support on CPU%d\n",
smp_processor_id());
for (i = 0; i < nr_mce_banks; i++) {
int cpu = smp_processor_id();
if (!mce_available(c) || !cmci_support) {
- printk(KERN_DEBUG "CMCI: CPU%d has no CMCI support\n", cpu);
+ mce_printk(MCE_QUIET, "CMCI: CPU%d has no CMCI support\n", cpu);
return;
}
apic = apic_read(APIC_CMCI);
if ( apic & APIC_VECTOR_MASK )
{
- printk(KERN_WARNING "CPU%d CMCI LVT vector (%#x) already installed\n",
+ mce_printk(MCE_QUIET, "CPU%d CMCI LVT vector (%#x) already installed\n",
cpu, ( apic & APIC_VECTOR_MASK ));
return;
}
if (bs.errcnt && mctc != NULL) {
if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) {
mctelem_commit(mctc);
- printk(KERN_DEBUG "CMCI: send CMCI to DOM0 through virq\n");
+ mce_printk(MCE_VERBOSE, "CMCI: send CMCI to DOM0 through virq\n");
send_guest_global_virq(dom0, VIRQ_MCA);
} else {
x86_mcinfo_dump(mctelem_dataptr(mctc));
if (l & MCG_EXT_P)
{
nr_intel_ext_msrs = (l >> MCG_EXT_CNT) & 0xff;
- printk (KERN_INFO "CPU%d: Intel Extended MCE MSRs (%d) available\n",
+ mce_printk (MCE_QUIET, "CPU%d: Intel Extended MCE MSRs (%d) available\n",
smp_processor_id(), nr_intel_ext_msrs);
}
firstbank = mce_firstbank(c);
if (!(l | h))
{
/* if ctl is 0, this bank is never initialized */
- printk(KERN_DEBUG "mce_init: init bank%d\n", i);
+ mce_printk(MCE_VERBOSE, "mce_init: init bank%d\n", i);
wrmsr (MSR_IA32_MC0_CTL + 4*i, 0xffffffff, 0xffffffff);
wrmsr (MSR_IA32_MC0_STATUS + 4*i, 0x0, 0x0);
}
int intel_mcheck_init(struct cpuinfo_x86 *c)
{
_mce_cap_init(c);
- printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
+ mce_printk(MCE_QUIET, "Intel machine check reporting enabled on CPU#%d.\n",
smp_processor_id());
/* machine check is available */
switch ( msr )
{
case MSR_IA32_MC0_CTL2 ... MSR_IA32_MC0_CTL2 + MAX_NR_BANKS - 1:
- gdprintk(XENLOG_WARNING, "We have disabled CMCI capability, "
+ mce_printk(MCE_QUIET, "We have disabled CMCI capability, "
"Guest should not write this MSR!\n");
break;
default:
switch ( msr )
{
case MSR_IA32_MC0_CTL2 ... MSR_IA32_MC0_CTL2 + MAX_NR_BANKS - 1:
- gdprintk(XENLOG_WARNING, "We have disabled CMCI capability, "
+ mce_printk(MCE_QUIET, "We have disabled CMCI capability, "
"Guest should not read this MSR!\n");
break;
default: